<?php
/**
 * Created by PhpStorm.
 * User: zwc
 * Date: 2022/2/5
 * Time: 1:10
 */

namespace App\Service\Users;


use App\Dao\User\UserDao;
use App\Dao\User\UserSpreadDao;
use App\Dao\User\UserSpreadSettingDao;
use App\Dao\Users\UsersDao;
use App\Library\User\UserInvitationCode;
use App\Model\User\UserSpread;
use App\Service\BaseService;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;

class UsersService extends BaseService
{
    /**
     * @Inject()
     * @var UserSpread
     */
    protected $userSpread;

    /**
     * @Inject()
     * @var UsersDao
     */
    protected $usersDao;


    public function regAndLogin($mobile, $params)
    {
        $this->register($mobile, $params);
        return $this->login($mobile);
    }

    public function login($mobile)
    {
        $users = $this->usersDao->params(compact('mobile'))->first();
        $token = $this->getToken($users->id);
        return compact('token');
    }

    public function register($mobile, $params)
    {
        if ($users = $this->usersDao->DaoWhere(compact('mobile'))->first()) {
            $users->fill($params);
            return $users->save();
        }
        return $this->usersDao->create(compact('mobile') + $params);
    }

    public function getToken($usersId)
    {
        $token_pre = 'token:';
        //生成随机树
        $token = time() . rand(10000, 9999999) . $usersId;
        if ($this->redis->set($token_pre . $token, $usersId)) {

        } else {
            err('获取token失败');
        }

        return $token;
    }

    public function checkToken($token)
    {
        $token_pre = 'token:';
        if (!$this->redis->exists($token_pre . $token)) {
            return false;
        }
        $uid = $this->redis->get($token_pre . $token);
        return $uid;
    }

    public function invoice(mixed $uid, string $code)
    {
        $spread_uid = UserInvitationCode::init($code)->decode();
        return $this->userSpread->firstOrCreate([
            'uid' => $uid,
            'spread_uid' => $spread_uid,
        ]);
    }

    public function bind($userId, $code)
    {
        Db::beginTransaction();
        try {
            //判断验证码是否存在
            $isExist = $this->usersDao->where('uid', $code)->exists();
            if (!$isExist) {
                _Error('邀请码不存在');
            }
            $user = $this->usersDao->where('uid', $userId)->lockForUpdate()->firstOrError();
            if ($user->spread_uid > 0) {
                _Error('已经绑定了');
            }
            App(UserSpreadDao::class)->create([
                'uid' => $userId,
                'spread_uid' => $code,
                'spread_time' => time()
            ]);
            $user->spread_uid = $code;
            $user->spread_time = time();
            $user->save();
        } catch (\Exception $e) {
            Db::rollBack();
            _Error($e->getMessage());
        }
        Db::commit();
        return true;
    }

    public function lists(\App\Tool\Collect $params)
    {
        $data = $this->usersDao->lists($params);
        return $data;
    }


    public function getBindDetail(int $user_id)
    {
        $my_uid = $user_id;
        $spread_uid = App(UserDao::class)->where('uid', $my_uid)->value('spread_uid') ?: '';
        return compact('user_id', 'spread_uid');
    }

    public function spreadEvent()
    {
        Db::beginTransaction();
        try {
            $user = $this->usersDao->where('is_spread', 0)->first();
            $uid = $user ? $user->spread_uid : 0;
            if ($user) {
                $user->is_spread = 1;
                $user->save();

                //邀请人数
                $people = $this->usersDao->getSpreadPeople($uid);
                
                $num = app(UserSpreadSettingDao::class)->where('people', $people)->value('num');
                if ($num) {
                    app(UserDao::class)->opAccount('integral', $uid, $num, 'spread', 0);
                }
            }
        } catch (\Exception $e) {
            Db::rollBack();
            _Error($e->getMessage());
        }
        Db::commit();
        return true;
    }
}